﻿Namespace IO
    Public Class BlockStreamReader
        Private mStream As System.IO.Stream
        Public Sub New(ByVal stream As System.IO.Stream)
            mStream = stream
        End Sub

        Public Function ReadString() As String
            Return ReadString(mStream)
        End Function

        Public Function ReadBytes() As Byte()
            Return ReadBytes(mStream)
        End Function

        Public Function ReadByte() As Byte
            Return CByte(mStream.ReadByte)
        End Function

        Public Function ReadInteger() As Integer
            Return ReadInteger(mStream)
        End Function
        Public Function ReadLong() As Long
            Return ReadLong(mStream)
        End Function
        Public Function ReadShort() As Short
            Return ReadShort(mStream)
        End Function
        Public Function ReadBoolean() As Boolean
            Return ReadBoolean(mStream)
        End Function

        Public Shared Function ReadLong(ByVal stream As System.IO.Stream) As Long
            Dim bData(7) As Byte
            For i As Integer = 0 To 7
                bData(i) = CByte(stream.ReadByte)
            Next
            Return BitConverter.ToInt32(bData, 0)
        End Function
        Public Shared Function ReadInteger(ByVal stream As System.IO.Stream) As Integer
            Dim bData(3) As Byte
            For i As Integer = 0 To 3
                bData(i) = CByte(stream.ReadByte)
            Next
            Return BitConverter.ToInt32(bData, 0)
        End Function
        Public Shared Function ReadShort(ByVal stream As System.IO.Stream) As Short
            Dim bData(1) As Byte
            For i As Short = 0 To 1
                bData(i) = CByte(stream.ReadByte)
            Next
            Return BitConverter.ToInt16(bData, 0)
        End Function
        Public Shared Function ReadBytes(ByVal stream As System.IO.Stream) As Byte()
            Dim iLen As Integer = ReadInteger(stream)
            If iLen = 0 Then
                Return New Byte() {}
            ElseIf iLen < 10485760 Then
                Return ReadBytesFixedCount(stream, iLen)
            Else
                Throw New ArgumentOutOfRangeException("Size of byte block exceeds 10 Mb which is considered corrupt!")
            End If
        End Function
        Public Shared Function ReadBytesFixedCount(ByVal stream As System.IO.Stream, ByVal count As Integer) As Byte()
            Dim bData(count - 1) As Byte
            Dim iToRead As Integer = count
            Dim iPos As Integer = 0
            While iToRead > 0
                Dim iRead As Integer = stream.Read(bData, iPos, iToRead)
                iToRead -= iRead
                iPos += iRead
            End While
            Return bData
        End Function
        Public Shared Function ReadRawBytes(ByVal stream As System.IO.Stream, ByVal count As Integer) As Byte()
            Dim bRet(count - 1) As Byte
            Dim iRead As Integer = 0
            While iRead < count
                Dim iReadNow As Integer
                iReadNow = stream.Read(bRet, iRead, count - iRead)
                iRead += iReadNow
            End While
            Return bRet
        End Function
        Public Shared Sub ReadRawBytes(ByVal stream As System.IO.Stream, ByVal buffer() As Byte, ByVal offset As Integer, ByVal count As Integer)
            Dim iRead As Integer = 0
            While iRead < count
                Dim iReadNow As Integer
                iReadNow = stream.Read(buffer, iRead + offset, count - iRead)
                iRead += iReadNow
            End While
        End Sub

        Public Shared Function ReadString(ByVal stream As System.IO.Stream) As String
            Dim bData() As Byte = ReadBytes(stream)
            Return System.Text.Encoding.UTF8.GetString(bData)
        End Function

        'Public Shared Function ReadShort(ByVal stream As System.IO.Stream) As Short
        '    Dim bData(1) As Integer
        '    For i As Integer = 0 To 1
        '        bData(i) = stream.ReadByte
        '    Next
        '    Dim iRet As Short
        '    For i As Integer = 0 To 1
        '        Dim iVal As Integer = bData(i)
        '        iRet += CShort(CInt(256 ^ i) * iVal)
        '    Next
        '    Return iRet
        'End Function

        Public Shared Function ReadBoolean(ByVal stream As System.IO.Stream) As Boolean
            Return stream.ReadByte = 1
        End Function

        Public Shared Function ReadAsciiChars(ByVal stream As System.IO.Stream, ByVal count As Integer) As String
            Dim bBuf(count - 1) As Byte
            stream.Read(bBuf, 0, count)
            Return System.Text.Encoding.ASCII.GetString(bBuf)
        End Function

    End Class

End Namespace